package com.h2cloud.Proxy._4_cglibProxy;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;

/**
 * @Package: com.h2cloud.Proxy._4_cglibProxy
 * @ClassName: _1_method_invoke
 * @Author: h2cloud
 * @CreateTime: 2023/8/9 11:47 下午
 * @Description:
 */

public class _1_method_invoke {
	static class Target {
		public void foo() {
			System.out.println("target foo");
		}
	}

	// 代理是子类型, 目标是父类型
	public static void main(String[] param) {
		// 目标对象
		Target target = new Target();

		/**
		 *  创建一个代理类
		 *  参数：1、目标类本身； 2、回调函数，决定代理类中方法执行的行为
		 *      回调函数的参数：1、代理类对象本身； 2、当前被代理类中执行的方法； 3、方法执行的实际参数
		 */
		// 子类型的对象可以转换为父类型，所以Proxy可以转换为Target
		Target proxy = (Target) Enhancer.create(
				Target.class,
				(MethodInterceptor) (p, method, args, methodProxy) -> {
					//模拟前置增强
					System.out.println("before...");
					// 方法一：用方法反射调用目标
					// Object result = method.invoke(target, args);
					// 方法二：内部没有用反射, 需要目标（spring使用的是这种方法）
					// Object result = methodProxy.invoke(target, args);
					// 方法三：内部没有用反射, 需要代理类对象，不需要目标类对象
					Object result = methodProxy.invokeSuper(p, args);
					//模拟后置增强
					System.out.println("after...");
					return result;
				});
		proxy.foo();
	}
}
